﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;
using TpLogger.Properties;

namespace TpLogger {

    public class Logger {

        #region Members

        public delegate void MessageAddedEventHandler(string message);
        public event MessageAddedEventHandler MessageAdded;
        private bool hasErrors;
        private List<LogItem> logList;
        private string file;

        public class LogItem {
            public DateTime logDate;
            public string message;

            public LogItem(string message) {
                logDate = DateTime.Now;
                this.message = message;
            }

            public override string ToString() {
                return logDate.ToString("yy-MM-dd HH:mm:ss") + ": " + message;
            }

        }

        #endregion

        #region Constructor

        public Logger() {

            hasErrors = false;
            logList = new List<LogItem>();
            this.file = GetFilename();
        }

        public Logger(string fileName)
            : this() {
            this.file = fileName;
        }

        #endregion

        #region Properties

        public string FileName {
            get { return this.file; }
            set { this.file = value; }
        }

        public bool HasErrors {
            get { return hasErrors; }
        }

        public int LogListCount {
            get { return logList.Count; }
        }

        public bool Abort {
            get;
            set;
        }

        #endregion

        #region Methods

        public void Add(string message) {
            Add(message, false);
        }

        public void Add(string message, Exception ex) {
            Exception x = ex.InnerException;
            System.Text.StringBuilder msg = new StringBuilder("***" + message + ": " + ex.Message);
            while(x != null) {
                msg.AppendFormat("\r\n{0}", x.Message);
                x = x.InnerException;
            }
            msg.Append("\r\n----Stacktrace----\r\n");
            msg.Append(ex.StackTrace);
            Add(msg.ToString(), false);
            this.FileName = this.FileName.Replace("Log", "Error");
            hasErrors = true;
        }

        public void Add(string message, bool isError) {
            LogItem newEntry = new LogItem(message);
            logList.Add(newEntry);

            this.hasErrors |= isError;
            if(MessageAdded != null)
                MessageAdded(message);
        }

        public void ResetErrors(bool err) {
            this.hasErrors = err;
        }

        public void SaveToDisk() {
            string logPath = Settings.Default.LogFilePath;
            if(logPath.Length > 0 && !(Directory.Exists(logPath))) {
                Directory.CreateDirectory(logPath);
            }
            string logFileName = Path.Combine(logPath, file);
            TextWriter logFile = File.CreateText(logFileName);
            logFile.WriteLine(this.ToString());
            logFile.Flush();
            logFile.Close();
        }

        public void SendByEMail(string subject, string mailTo) {
            try {
                MailMessage mailMessage = new MailMessage();
                string strPassword = Settings.Default.MailPassword;

                mailMessage.From = new MailAddress(Settings.Default.MailSender);
                if(mailTo == null | mailTo == string.Empty) {
                    foreach(string thisAddress in Settings.Default.MailTo.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) {
                        if(thisAddress.Trim() != "") {
                            mailMessage.To.Add(thisAddress.Trim());
                        }
                    }
                } else {
                    foreach(string thisAddress in mailTo.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) {
                        if(thisAddress.Trim() != "") {
                            mailMessage.To.Add(thisAddress.Trim());
                        }
                    }
                }

                if(subject == null | subject == string.Empty) {
                    mailMessage.Subject = "Fehlerprotokoll: " + DateTime.Today.ToString("yy-MM-dd");
                } else {
                    mailMessage.Subject = subject;
                }

                mailMessage.IsBodyHtml = false;
                mailMessage.Body = Environment.NewLine + this.ToString();

                SmtpClient smtpClient = new SmtpClient(Settings.Default.MailServer);

                smtpClient.Credentials = new NetworkCredential(Settings.Default.MailUsername, strPassword);

                smtpClient.Send(mailMessage);

                mailMessage.Dispose(); //Have to do this otherwise the reference to the file is not released

            } catch(Exception ex) {
                Add("SendByEmail: ", ex);
            }
        }

        public override string ToString() {
            StringBuilder returnValue = new StringBuilder();
            foreach(var thisLogItem in logList) {
                returnValue.AppendLine(thisLogItem.ToString());
            }
            return returnValue.ToString();
        }

        #endregion

        #region Functions

        private string GetFilename() {

            return "Log" + Environment.UserName + DateTime.Now.ToString("yyMMddHHmm") + ".txt";
        }

        #endregion

    }


}
